package com.coldworks.base.manager;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import android.content.Context;
import android.graphics.Bitmap;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.util.Pair;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;

import com.coldworks.base.util.BaseCONST;
import com.coldworks.coldjoke.R;

public class BaseSplashManager {
	protected final Logger log = LoggerFactory.getLogger(this.getClass());
	private static BaseSplashManager instance = null;

	public static BaseSplashManager getInstance() {
		if (instance == null) {
			synchronized (BaseSplashManager.class) {
				if (instance == null) {
					instance = new BaseSplashManager();
				}
			}
		}
		return instance;
	}

	private BaseSplashManager() {
	}

	private CountDownTimer splashCDT = null; // 欢迎页的倒计时
	private FrameLayout splashContainer = null; // 欢迎页容器
	private ImageView splashIV = null; // 欢迎页图片
	private Handler handler = null; // 传递“完成”信息

	private interface CallBack {
		void execute();
	}

	private class SplashCallBack implements CallBack {
		private Context ctx;
		private boolean versionFirst;

		public SplashCallBack(Context context, boolean versionFirst) {
			this.ctx = context;
			this.versionFirst = versionFirst;
		}

		@Override
		public void execute() {
			splashDone(ctx, versionFirst);
		}
	}

	public View show(Context context, boolean versionFirst, Handler handler) {
		try {
			final SplashCallBack scb = new SplashCallBack(context, versionFirst);
			this.handler = handler;
			// 生成歡迎页，设为可见
			this.splashIV = new ImageView(context);
			this.splashIV.setLayoutParams(new LinearLayout.LayoutParams(
					ViewGroup.LayoutParams.FILL_PARENT,
					ViewGroup.LayoutParams.FILL_PARENT));
			this.splashIV.setVisibility(View.VISIBLE);
			this.splashIV.setScaleType(ScaleType.CENTER_CROP);
			// 生成歡迎页計時器
			this.splashCDT = new CountDownTimer(
					BaseCONST.TASK.SPLASH_SECOND * 1000, 1000) {
				@Override
				public void onTick(long millisUntilFinished) {
				}

				@Override
				public void onFinish() {
					// 計時完成時，執行這個
					scb.execute();
				}
			};
			this.splashIV.setOnClickListener(new OnClickListener() {
				@Override
				public void onClick(View v) {
					splashCDT.cancel();
					scb.execute();
				}
			});
			// 歡迎页計時器开始
			this.splashCDT.start();
			// 同步加载当前日期欢迎页
			String splashToday = BaseSplashManager.getInstance()
					.getSplashTodayName();
			Bitmap bitMap = BaseSplashManager.getInstance().getSplashImg(
					context, splashToday);
			if (bitMap == null) { // 这里表示今天没有特殊splash，使用默认鸡蛋
				log.info("splashToday: " + splashToday
						+ " not found. use default");
				bitMap = BaseSplashManager.getInstance().getSplashDefault(
						context);
			} else { // 这里表示已经加载到了当前日期的特殊splash
				log.info("splashToday: " + splashToday);
			}
			if (bitMap != null) {
				this.splashIV.setImageBitmap(bitMap);
			}

			// firstView是用来展示splash和功能引导页的容器
			this.splashContainer = new FrameLayout(context);
			this.splashContainer.setLayoutParams(new ViewGroup.LayoutParams(
					ViewGroup.LayoutParams.FILL_PARENT,
					ViewGroup.LayoutParams.FILL_PARENT));
			this.splashContainer.addView(this.splashIV);
			log.info("start");
			// 这个返回将由父类使用，并置顶为用户首先看到的view，其实导航操作(首页loading)已经在它的掩盖下执行了
			return this.splashContainer;
		} catch (Exception e) {
			log.error("", e);
		}
		return null;

	}

	/**
	 * splash完成之后的回调
	 */
	public void splashDone(Context context, boolean versionFirst) {
		// if (versionFirst) {
		// BaseGallery splashVersion = this.getSplashVersion(context);
		// this.splashContainer.addView(splashVersion);
		// BasePrefManager.getInstance().setIntToPrefs(context,
		// BaseCONST.KEY.SHOW_GUIDE,
		// BaseConfManager.getInstance().getVersionCode(context));
		// this.splashIV.setVisibility(View.GONE);
		// } else {
		// 先配置一个动画，真正走下一步的操作放在动画结束处调用
		AlphaAnimation alphaAnimation = new AlphaAnimation(1, 0);
		alphaAnimation.setDuration(500);
		alphaAnimation.setAnimationListener(new AnimationListener() {
			@Override
			public void onAnimationStart(Animation animation) {
			}

			@Override
			public void onAnimationRepeat(Animation animation) {
			}

			@Override
			public void onAnimationEnd(Animation animation) {
				log.info("scaleout");
				BaseSplashManager.this.splashIV.setVisibility(View.GONE);
				Message msg = new Message();
				msg.what = BaseCONST.OP.SPLASH_GONE;
				msg.setTarget(handler);
				msg.sendToTarget();
			}
		});
		// splash执行淡出动画
		this.splashIV.startAnimation(alphaAnimation);
		this.splashIV.setOnClickListener(null);
	}

	// /**
	// * 启动新功能导航页，第一次运行程序时显示
	// */
	// private BaseGallery getSplashVersion(Context context) {
	//
	// List<Integer> guides = new ArrayList<Integer>();
	// guides.add(R.drawable.guide0);
	// guides.add(R.drawable.guide1);
	// BaseGuideAdapter adp = new BaseGuideAdapter(context, guides);
	//
	// final BaseGallery guideGallery = new BaseGallery(context, null);
	// FrameLayout.LayoutParams glp = new FrameLayout.LayoutParams(
	// ViewGroup.LayoutParams.FILL_PARENT,
	// ViewGroup.LayoutParams.FILL_PARENT);
	// glp.gravity = Gravity.CENTER;
	// guideGallery.setLayoutParams(glp);
	// guideGallery.setUnselectedAlpha(255);
	// guideGallery.setVisibility(View.VISIBLE);
	// guideGallery.setAdapter(adp);
	// guideGallery.setFadingEdgeLength(0);
	// guideGallery.setSpacing(0);
	// guideGallery.setOnItemSelectedListener(new OnItemSelectedListener() {
	//
	// @Override
	// public void onItemSelected(AdapterView<?> arg0, View arg1,
	// int position, long arg3) {
	//
	// nowPosition = position;
	//
	// if (position == 1) {
	// log.info(this, "select", String.valueOf(position));
	// guideGallery.setVisibility(View.GONE);
	// guideGallery.setTag(null);
	// Message msg = new Message();
	// msg.what = BaseCONST.OP.SPLASH_GONE;
	// msg.setTarget(handler);
	// msg.sendToTarget();
	// }
	// }
	//
	// @Override
	// public void onNothingSelected(AdapterView<?> arg0) {
	// }
	// });
	// guideGallery
	// .setOnItemClickListener(new AdapterView.OnItemClickListener() {
	// @Override
	// public void onItemClick(AdapterView<?> arg0, View arg1,
	// int arg2, long arg3) {
	//
	// if (nowPosition == 0) {
	// guideGallery.setVisibility(View.GONE);
	// guideGallery.setTag(null);
	// Message msg = new Message();
	// msg.what = BaseCONST.OP.SPLASH_GONE;
	// msg.setTarget(handler);
	// msg.sendToTarget();
	// } else {
	// guideGallery.setSelection(nowPosition + 1);
	// }
	//
	// }
	// });
	// return guideGallery;
	// }

	/**
	 * 获取本地splash文件名列表
	 */
	public List<String> getSplashNameList(File splashDir) {
		if (splashDir == null || !splashDir.exists()
				|| !splashDir.isDirectory()) {
			return null;
		}
		List<String> fileName = new ArrayList<String>();
		for (File one : splashDir.listFiles()) {
			String name = one.getName();
			if (splashValid(name)) { // 判断是图片
				fileName.add(name);
			} else {
				try {
					one.delete();
				} catch (Exception e) {
					log.error("", e);
				}
			}
		}
		return fileName;
	}

	/**
	 * 判断splash名是否合法
	 */
	public boolean splashValid(String name) {
		return Pattern.matches(BaseCONST.SPLASH.SPLASH_REGEX_FULL, name);
	}

	/**
	 * 根据splash名得到其中的日期名
	 */
	public String splashDate(String name) {
		return name.replaceAll(BaseCONST.SPLASH.SPLASH_REGEX_V, "");
	}

	/**
	 * 根据splash名得到其中的版本号
	 */
	public Integer splashVersion(String name) {
		Matcher date = BaseCONST.SPLASH.SPLASH_PATTERN_V.matcher(name);
		if (date.find()) {
			return Integer.valueOf(date.group());
		}
		return 0;
	}

	/**
	 * 返回当日的splash文件名
	 */
	public String getSplashTodayName() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); // 获得日期
		return "splash" + sdf.format(new java.util.Date());
	}

	/**
	 * 根据当日的splash文件名读取Bitmap文件
	 */
	public Bitmap getSplashImg(Context context, String splashToday) {
		Bitmap bitMap = null;
		File splashDir = BaseStorageManager.getInstance().getSplashDir();
		if (splashDir != null) {
			List<String> splashImageList = this
					.getSplashNameList(BaseStorageManager.getInstance()
							.getSplashDir());
			for (String one : splashImageList) {
				if (one.startsWith(splashToday)) {
					try {
						bitMap = BaseBitmapManager.getInstance()
								.getBitmapByFile(
										context,
										new File(splashDir.getAbsolutePath()
												+ File.separator + one));
					} catch (Exception e) {
						log.error("", e);
					}
					break;
				}
			}
		}
		return bitMap;
	}

	/**
	 * 读取默认splash的Bitmap文件
	 */
	public Bitmap getSplashDefault(Context context) {
		return BaseBitmapManager.getInstance().getBitmapByResid(context,
				R.drawable.splash);
	}

	public void splashSync(Context context, String syncSplashUrl) {
		try {
			String result = BaseNetworkManager.getInstance().httpGET(context,
					syncSplashUrl);
			if (result == null) {
				log.warn("http return null");
				return;
			}
			JSONObject json = new JSONObject(result);
			JSONObject resp = new JSONObject(json.getString("resp"));
			String downloadUrlPfx = resp.getString("url");
			JSONArray array = resp.getJSONArray("pics");
			Map<String, Pair<String, Integer>> serverSplashNameMap = new HashMap<String, Pair<String, Integer>>();
			for (int i = 0; i < array.length(); i++) {
				String name = array.getString(i);
				if (!this.splashValid(name)) {
					log.warn("why server return: " + name);
					continue;
				}
				String date = this.splashDate(name);
				Integer version = this.splashVersion(name);
				serverSplashNameMap.put(date, new Pair<String, Integer>(name,
						version));
			}
			this.mergeSplash(downloadUrlPfx, serverSplashNameMap);
		} catch (JSONException e) {
			log.error("", e);
			return;
		}
	}

	/**
	 * 参照服务器文件列表，本地文件用此方法进行增删改同步 1.服务器有，本地没有的，将进行下载添加 2.服务器的版本比本地版本高的，将进行下载替换
	 * 3.服务器没有，本地有的，将进行本地删除 参数：服务器文件名列表
	 */
	private void mergeSplash(String downloadUrlPfx,
			Map<String, Pair<String, Integer>> serverSplashNameMap) {
		File splashDir = BaseStorageManager.getInstance().getSplashDir();
		// 首先获取本地文件列表
		List<String> localSplashNameList = this.getSplashNameList(splashDir);
		if (localSplashNameList == null) {
			log.warn("no sdcard");
			return;
		}
		Map<String, Pair<String, Integer>> localSplashNameMap = new HashMap<String, Pair<String, Integer>>();
		for (String name : localSplashNameList) {
			if (!this.splashValid(name)) {
				log.warn("why server return: " + name);
				continue;
			}
			String date = this.splashDate(name);
			Integer version = this.splashVersion(name);
			localSplashNameMap.put(date, new Pair<String, Integer>(name,
					version));
		}

		Map<String, String> splashToAdd = new HashMap<String, String>();
		List<String> splashToDel = new ArrayList<String>();

		for (Entry<String, Pair<String, Integer>> local : localSplashNameMap
				.entrySet()) {
			Pair<String, Integer> server = serverSplashNameMap.get(local
					.getKey());
			if (server == null) {
				// 本地有，服务器没有的
				splashToDel.add(local.getValue().first);
			} else if (server.second > local.getValue().second) {
				// 本地有，服务器也有，但是服务器版本更高的
				splashToDel.add(local.getValue().first);
				splashToAdd.put(local.getKey(), server.first);
				serverSplashNameMap.remove(local.getKey());
			} else {
				serverSplashNameMap.remove(local.getKey());
			}
		}
		// 本地没有，服务器有的
		for (Entry<String, Pair<String, Integer>> server : serverSplashNameMap
				.entrySet()) {
			splashToAdd.put(server.getKey(), server.getValue().first);
		}
		this.delete(splashDir, splashToDel);
		this.update(downloadUrlPfx, splashDir, splashToAdd);
	}

	/**
	 * 删除过期的splash文件 需要fileNameList
	 **/
	private void delete(File splashDir, List<String> splashToDel) {
		if (splashDir == null) {
			return;
		}
		for (String one : splashToDel) {
			log.info("deleting: " + one);
			File file = new File(splashDir.getAbsolutePath() + File.separator
					+ one); // 获取接收进来的路径
			if (file.exists()) {
				try {
					file.delete();
				} catch (Exception e) {
					log.error("", e);
				}
			}
		}
	}

	/**
	 * 更新本地splash
	 */
	private void update(String downloadUrlPfx, File splashDir,
			Map<String, String> splashToAdd) {
		if (splashDir == null) {
			return;
		}
		for (Entry<String, String> one : splashToAdd.entrySet()) {
			String filePath = splashDir.getAbsolutePath() + File.separator
					+ one.getValue();
			String downloadUrl = downloadUrlPfx + one.getKey();
			try {
				File localFile = new File(filePath);
				if (localFile.exists()) {
					localFile.delete();
					localFile.createNewFile();
				}
				// int bytesum = 0;
				int byteread = 0;
				FileOutputStream fos = new FileOutputStream(filePath);
				try {
					InputStream is = new URL(downloadUrl).openStream();
					byte[] buffer = new byte[4096];
					while ((byteread = is.read(buffer)) != -1) {
						// bytesum += byteread;
						fos.write(buffer, 0, byteread);
					}
					is.close();
				} catch (Exception e) {
					log.error("", e);
					localFile.delete();
				}
				log.info("dowloading: " + downloadUrl + " to " + filePath);
				fos.close();
			} catch (Exception e) {
				log.error("", e);
			}
		}
	}

}
